package com.kingtown.inventory;


import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.widget.Toast;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.google.gson.Gson;
import com.kingtown.inventory.adapter.AssetAdapter;
import com.kingtown.inventory.domain.dto.AssetDto;
import com.kingtown.inventory.domain.dto.KiClient;
import com.kingtown.inventory.domain.dto.KiFloor;
import com.kingtown.inventory.domain.dto.KiPosition;
import com.rscja.deviceapi.RFIDWithUHFUART;
import com.rscja.deviceapi.entity.UHFTAGInfo;
import com.kingtown.inventory.net.NetWorkManager;

import java.util.*;
import java.util.stream.Collectors;

public class MainApplication extends Application {
    public RFIDWithUHFUART mReader;
    private float volumnRatio;
    private AudioManager am;
    private HashMap<Integer, Integer> soundMap = new HashMap<>();
    private SoundPool soundPool;
    SharedPreferences sp;
    public Gson gson = new Gson();
    Handler handler;
    public boolean loopFlag;

    public String deviceSerial = "";

    public AssetAdapter assetAdapter;
    public List<String> cacheEpcList = new ArrayList<>();
    public List<AssetDto> showList = new ArrayList<>();
    public List<AssetDto> assetList = new ArrayList<>();
    public List<AssetDto> rawList = new ArrayList<>();
    public Map<String, AssetDto> rawMap = new HashMap<>();
    public int showMode = 0;

    MainApplication _this;
    public KiClient selectClient;
    public KiFloor selectFloor;
    public KiPosition selectPosition;

    public int mode = 1; //1-盘点 2-出库 3-找货

    public List<String> searchList = new ArrayList<>();

    @SuppressLint("HandlerLeak")
    @Override
    public void onCreate() {
        super.onCreate();

        SharedPreferences sharedPreferences = getSharedPreferences("application", 0);
        this.sp = sharedPreferences;
        _this = this;
        initSound();
        initUHF();

        NetWorkManager netWorkManager = NetWorkManager.getInstance();
        netWorkManager.init();

        this.handler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 1:
                        Log.i("read epc ", msg.obj.toString());
                        handleEpc(msg.obj.toString());
                        break;
                    case 2:
                        Utils.showProgressDialog((Context) msg.obj, "提示", "数据请求中");
                        break;
                }
            }
        };

        //获取设备序列号
//        deviceSerial = "123";
        deviceSerial = Settings.Global.getString(this.getContentResolver(), "Serial");

        //初始化adapter
        initAdapter();
    }

    private void initAdapter() {
        assetAdapter = new AssetAdapter(assetList, _this);
    }

    private void initSound() {
        this.soundPool = new SoundPool(10, 3, 5);
        this.soundMap.put(1, Integer.valueOf(this.soundPool.load(this, R.raw.barcodebeep, 1)));
        this.soundMap.put(2, Integer.valueOf(this.soundPool.load(this, R.raw.serror, 1)));
        this.soundMap.put(3, Integer.valueOf(this.soundPool.load(this, R.raw.success, 1)));
        this.am = (AudioManager) getSystemService(AUDIO_SERVICE);
    }


    public void initUHF() {
        try {
            if (mReader != null) {
                return;
            }
            mReader = RFIDWithUHFUART.getInstance();
            mReader.init();
        } catch (Exception ex) {
            Toast.makeText(this, "初始化失败", Toast.LENGTH_SHORT).show();
        }
    }

    public void playSound(int id) {
        this.volumnRatio = ((float) this.am.getStreamVolume(3)) / ((float) this.am.getStreamMaxVolume(3));
        try {
            int intValue = this.soundMap.get(Integer.valueOf(id)).intValue();
            float f = this.volumnRatio;
            soundPool.play(intValue, f, f, 1, 0, 1.0f);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String readTag() {
        UHFTAGInfo uhftagInfo = mReader.inventorySingleTag();
        if (uhftagInfo != null) {
            playSound(1);
            return uhftagInfo.getEPC();
        } else {
            Toast.makeText(this, "读取标签失败", Toast.LENGTH_SHORT).show();
            playSound(2);
            return null;
        }
    }

    public boolean startInventory() {
        if (loopFlag) {
            return true;
        }
        if (mReader.startInventoryTag()) {
            this.loopFlag = true;
            new TagThread().start();
            return true;
        } else {
            mReader.stopInventory();
            Toast.makeText(this, "开始读码失败", Toast.LENGTH_SHORT).show();
            return false;
        }
    }

    public boolean stopInventory() {
        if (this.loopFlag) {
            this.loopFlag = false;
            if (this.mReader.stopInventory()) {
                return true;
            }
            Toast.makeText(this, "停止读码失败", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    class TagThread extends Thread {
        public void run() {
            UHFTAGInfo res = null;
            while (loopFlag) {
                res = mReader.readTagFromBuffer();
                if (res != null) {
                    Message msg = handler.obtainMessage();
                    msg.what = 1;
                    msg.obj = res.getEPC();
                    handler.sendMessage(msg);
                }
            }
        }
    }


    @SuppressLint("NotifyDataSetChanged")
    private void handleEpc(String epc) {
        if (cacheEpcList.contains(epc)) {
            return;
        }

        switch (mode) {
            case 1:
                cacheEpcList.add(epc);
                AssetDto dto = assetList.stream().filter(s -> s.getAssetEpc().equals(epc)).findFirst().orElse(null);
                if (dto == null) {
                    AssetDto surplusDto = rawMap.get(epc);
                    if (surplusDto != null) {
                        surplusDto.setInventoryStatus(2);
                        assetList.add(surplusDto);
                    }
                } else {
                    dto.setInventoryStatus(1);
                }
                assetAdapter.notifyDataSetChanged();
                break;
            case 2:
                cacheEpcList.add(epc);
                AssetDto outDto = rawMap.get(epc);
                if (outDto != null) {
                    outDto.setInventoryStatus(4);
                    assetList.add(outDto);
                    assetAdapter.notifyDataSetChanged();
                }
                break;
            case 3:
                if (searchList.contains(epc)) {
                    playSound(1);
                } else {
                    cacheEpcList.add(epc);
                }
                break;
        }
    }

    public interface Callback {
        void onCallback(JSONObject res);
    }

    @SuppressLint("NotifyDataSetChanged")
    public void resetData() {
        Utils.hideProgressDialog();
        cacheEpcList.clear();
        assetList.clear();

        if (selectFloor != null && selectPosition != null) {
            assetList.addAll(rawList.stream().filter(s ->
                    selectPosition.getPosition().equals(s.getAssetPosition()) &&
                            selectFloor.getFloor().equals(s.getAssetFloor())).collect(Collectors.toList()));
        } else if (selectFloor != null) {
            assetList.addAll(rawList.stream().filter(s ->
                    selectFloor.getFloor().equals(s.getAssetFloor())).collect(Collectors.toList()));
        } else {
            assetList.addAll(rawList);
        }
        assetList.forEach(s -> {
            s.setInventoryStatus(0);
        });
        assetAdapter.notifyDataSetChanged();

    }

    private List<AssetDto> filterShowList() {
        return switch (showMode) {
            case 1 -> //未盘
                    assetList.stream().filter(s -> s.getInventoryStatus().equals("0")).collect(Collectors.toList());
            case 2 -> //已盘
                    assetList.stream().filter(s -> s.getInventoryStatus().equals("1")).collect(Collectors.toList());
            case 3 -> //多盘
                    assetList.stream().filter(s -> s.getInventoryStatus().equals("2")).collect(Collectors.toList());
            default -> assetList;
        };
    }
}
